<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>VarSetCapacity()</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
</head>
<body>

<h1>VarSetCapacity()</h1>

<p>Enlarges a variable's holding capacity or frees its memory. Normally, this is necessary only for unusual circumstances such as <a href="DllCall.htm">DllCall</a>.</p>

<pre class="Syntax">GrantedCapacity := VarSetCapacity(UnquotedVarName [, RequestedCapacity, FillByte])</pre>
<h3>Parameters</h3>
<dl>

  <dt>GrantedCapacity</dt>
  <dd><p>The number of bytes that Var can now hold, which will be greater then or equal to <em>RequestedCapacity</em>. If <em>VarName</em> is not a valid variable name (such as a literal string or number), 0 is returned. If the system has insufficient memory to make the change (very rare), an error dialog is displayed and the current capacity is returned - this behaviour may change in a future version.</p></dd>

  <dt>UnquotedVarName</dt>
  <dd><p>The name of the variable (<em>not in quotes</em>). For example: <code>VarSetCapacity(MyVar, 1000)</code>. This can also be a dynamic variable such as <code>Array%i%</code> or a <a href="../Functions.htm#ByRef">function's ByRef parameter</a>.</p></dd>

  <dt>RequestedCapacity</dt>
  <dd><p>If omitted, the variable's current capacity will be returned and its contents will not be altered. Otherwise, anything currently in the variable is lost (the variable becomes blank).</p>
      <p>Specify for <em>RequestedCapacity</em> the number of bytes that the variable should be able to hold after the adjustment. For Unicode strings, this should be the length times two. <em>RequestedCapacity</em> does not include the internal zero terminator. For example, specifying 1 would allow the variable to hold up to one byte in addition to its internal terminator. Note: the variable will auto-expand if the script assigns it a larger value later.</p> 
      <p>Since this function is often called simply to ensure the variable has a certain minimum capacity, for performance reasons, it shrinks the variable only when <em>RequestedCapacity</em> is 0. In other words, if the variable's capacity is already greater than <em>RequestedCapacity</em>, it will not be reduced (but the variable will still made blank for consistency).</p>
      <p>Therefore, to explicitly shrink a variable, first free its memory with <code>VarSetCapacity(Var, 0)</code> and then use <code>VarSetCapacity(Var, NewCapacity)</code> -- or simply let it auto-expand from zero as needed.</p>
      <p>For performance reasons, freeing a variable whose previous capacity was less than 64 characters (128 bytes in Unicode builds) might have no effect because its memory is of a permanent type. In this case, the current capacity will be returned rather than 0.</p>
      <p>For performance reasons, the memory of a variable whose capacity is less than 4096 bytes is not freed by storing an empty string in it (e.g. <code>Var := &quot;&quot;</code>). However, <code>VarSetCapacity(Var, 0)</code> does free it.</p>
      <p><a name="neg1"></a>In v1.0.44.03+, specify -1 for <em>RequestedCapacity</em> to update the variable's internally-stored string length to the length of its current contents. This is useful in cases where the variable has been altered indirectly, such as by passing its <a href="../Variables.htm#amp">address</a> via <a href="DllCall.htm">DllCall()</a>. In this mode, VarSetCapacity() returns the length in bytes rather than the capacity.</p></dd>

  <dt>FillByte</dt>
  <dd><p>This parameter is normally omitted, in which case the memory of the target variable is not initialized (instead, the variable is simply made blank as described above). Otherwise, specify a number between 0 and 255. Each byte in the target variable's memory area (its current capacity, which might be greater than <em>RequestedCapacity</em>) is set to that number.  Zero is by far the most common value, which is useful in cases where the variable will hold raw binary data such as a <a href="DllCall.htm#struct">DllCall structure</a>.</p></dd>

</dl>

<h3>Remarks</h3>
<p>In addition to its uses described at <a href="DllCall.htm#str">DllCall</a>, this function can also be used to enhance performance when building a string by means of gradual concatenation. This is because multiple automatic resizings can be avoided when you have some idea of what the string's final length will be. In such a case, <em>RequestedCapacity</em> need not be accurate: if the capacity is too small, performance is still improved and the variable will begin auto-expanding when the capacity has been exhausted. If the capacity is too large, some of the memory is wasted, but only temporarily because all the memory can be freed after the operation by means of <code>VarSetCapacity(Var, 0)</code> or <code>Var := &quot;&quot;</code>.</p>
<p><a href="_MaxMem.htm">#MaxMem</a> restricts only the automatic expansion that a variable does on its own. It does not affect <a href="VarSetCapacity.htm">VarSetCapacity</a>.</p>
<h3>Related</h3>
<p><a href="DllCall.htm">DllCall</a>, <a href="_MaxMem.htm">#MaxMem</a>, <a href="NumPut.htm">NumPut</a>, <a href="NumGet.htm">NumGet</a></p>
<h3>Example</h3>
<pre class="NoIndent"><em>; Optimize by ensuring MyVar has plenty of space to work with.</em>
VarSetCapacity(MyVar, 10240000)  <em>; ~10 MB</em>
Loop
{
    ...
    MyVar = %MyVar%%StringToConcatenate%
    ...
}</pre>

<pre class="NoIndent"><em>; Calculate required buffer space for a string.</em>
bytes_per_char := A_IsUnicode ? 2 : 1
max_chars := 500
max_bytes := max_chars * bytes_per_char

Loop 2
{
    <em>; Allocate space for use with DllCall.</em>
    VarSetCapacity(buf, max_bytes)

    if A_Index = 1
        <em>; Alter the variable indirectly via DllCall.</em>
        DllCall("wsprintf", <span class="red">"ptr", &amp;buf</span>, "str", "0x%08x", "uint", 4919)
    else
        <em>; Use "str" to update the length automatically:</em>
        DllCall("wsprintf", <span class="blue">"str", buf</span>, "str", "0x%08x", "uint", 4919)

    <em>; Concatenate a string to demonstrate why the length needs to be updated:</em>
    wrong_str := buf . "&lt;end&gt;"
    wrong_len := StrLen(buf)

    <em>; Update the variable's length.</em>
    VarSetCapacity(buf, -1)

    right_str := buf . "&lt;end&gt;"
    right_len := StrLen(buf)

    MsgBox,
    (
    Before updating
      String: %wrong_str%
      Length: %wrong_len%

    After updating
      String: %right_str%
      Length: %right_len%
    )
}
</pre>

</body>
</html>
